package api.action;

import api.model.ApiColumn;
import api.model.ApiTable;
import api.service.ApiColumnService;
import api.service.ApiTableService;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.action.VueResult;
import m.common.model.FieldMeta;
import m.common.model.LinkTableMeta;
import m.common.model.Model;
import m.common.model.config.ModelConfig;
import m.common.model.type.FieldType;
import m.common.model.util.ModelQueryList;
import m.common.model.util.QueryCondition;
import m.common.model.util.QueryOrder;
import m.html.VueFormResult;
import m.html.VueListResult;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.element.other.ItemsQuery;
import m.html.form.*;
import m.html.list.ListButton;
import m.html.list.ListCount;
import m.html.list.ListElement;
import m.html.list.SuccessMethod;
import m.system.db.DataSet;
import m.system.exception.MException;
import m.system.util.ClassUtil;
import m.system.util.JSONMessage;
import m.system.util.StringUtil;
import manage.action.ManageAction;
import manage.util.DictionaryUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@ActionMeta(name="api/apiColumn")
public class ApiColumnAction extends ManageAction {
    private ApiColumn model;

    public JSONMessage doSave() throws Exception {
        systemLog("模型","保存模型列信息");
        verifyAdminOperPower("manage_api_power");
        String msg=getService(ApiColumnService.class).save(model);
        return new JSONMessage(0,msg);
    }
    public JSONMessage doDelete() throws Exception {
        systemLog("模型","删除模型列信息");
        verifyAdminOperPower("manage_api_power");
        String msg=getService(ApiColumnService.class).delete(model);
        return new JSONMessage(0,msg);
    }
    public VueResult toEdit() throws Exception {
        verifyAdminOperPower("manage_api_power");
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            model= ModelQueryList.getModel(model,"*");
        }else if(null!=model&&!StringUtil.isSpace(model.getTable().getOid())){
            model.setNotnull("N");
            model.setIsinit("N");
            model.setType("STRING");
        }else{
            throw new MException(this.getClass(),"参数错误");
        }
        ModelForm form = new ModelForm("列模型");
        form.addItem(
            FormInput.input("字段","model.name").setPlaceholder("请输入字段").setDescription("只能输入小写字母数字和下划线"),
            FormInput.input("描述","model.description").setPlaceholder("请输入描述"),
            FormInput.radio("非空","model.notnull","api.model.ApiColumn!notnull"),
            FormInput.radio("类型","model.type","api.model.ApiColumn!type").setSpan(3),
            FormTest.test("model.type=='MODEL'",FormInput.selectItem("表","model.modelClass",actionUrl(ApiTableAction.class,"getSourceClassOptions")).setPlaceholder("请选择表").setSpan(3)),
            FormTest.test("model.type=='TABLE'",FormInput.selectItem("表","model.modelTable.oid",actionUrl(ApiTableAction.class,"getApiTablesOptions")).setPlaceholder("请选择表").setSpan(3)),
            FormTest.test("model.type=='STRING'",
                FormInput.number("长度","model.length","#,##0",0).setPlaceholder("请输入长度"),
                FormInput.input("字典","model.dictType").setPlaceholder("请输入字典属性").setSpan(2).setDescription("A:普通字典:填字典类型<br/> B:选项字典:格式填(值:名称,值:名称)")
            )
        )
        .addData("model",model)
        .addButton(
            FormButton.pri("保存","doSave")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("doSave",actionUrl("doSave"),"{model:this.model}")
                .success("backFlag")
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form);
    }
    @RequestMeta(params = {"tableOid"})
    public JSONMessage getModelColumnOption(String tableOid) throws Exception {
        verifyAdminOperPower("manage_api_power");
        return DictionaryUtil.toDictData(
            new ItemsQuery(ApiColumn.class,"description","name")
                .setTitleExpression("concat(#{name},' - ',ifnull(#{description},''))")
                .addCond(QueryCondition.eq("table.oid",tableOid))
                .addCond(QueryCondition.notEmpty("modelTable.oid"))
                .toItems()
        );
    }
    @RequestMeta(params = {"tableClass"})
    public JSONMessage getTableMetaColumn(String tableClass) throws Exception {
        JSONMessage result=new JSONMessage(0);
        verifyAdminOperPower("manage_api_power");
        Class<? extends Model> clazz= ClassUtil.getClass(Model.class,tableClass);
        List<JSONMessage> list= new ArrayList<>();
        JSONMessage ob=new JSONMessage();
        ob.push("name","oid");
        ob.push("desc","主键");
        ob.push("type", FieldType.STRING);
        ob.push("length",50);
        ob.push("notnull",true);
        list.add(ob);
        Map<String, FieldMeta> fms=ModelConfig.getFieldMetaMap(clazz);
        for(FieldMeta fm : fms.values()){
            JSONMessage obj=new JSONMessage();
            obj.push("name",fm.name());
            obj.push("desc",fm.description());
            obj.push("type",fm.type());
            obj.push("length",fm.length());
            obj.push("notnull",fm.notnull());
            obj.push("defaultValue",fm.defaultValue());
            list.add(obj);
        }
        Map<String, LinkTableMeta> lts=ModelConfig.getLinkTableMetaMap(clazz);
        for(LinkTableMeta lt : lts.values()){
            JSONMessage obj=new JSONMessage();
            obj.push("name",lt.name());
            obj.push("desc",lt.description());
            obj.push("class",lt.table().getName());
            obj.push("notnull",lt.notnull());
            list.add(obj);
        }
        result.push("sourceCols",list);
        return result;
    }
    @RequestMeta(params = {"tableOid"})
    public JSONMessage updateColumns(String tableOid) throws Exception {
        ApiTable at=ModelQueryList.getModel(ApiTable.class,tableOid,"*");
        DataSet ds=getService(ApiTableService.class).getTableColumns(at.getName());
        getService(ApiTableService.class).updateTableColumns(at,ds);
        return new JSONMessage(0,"更新成功");
    }
    public VueResult apiColumnList() throws Exception{
        String tableOid=getParamsValue("tableOid");
        setOrder(QueryOrder.asc("oid"));
        ApiTable at=ModelQueryList.getModel(ApiTable.class,tableOid,"*");
        boolean isEdit= getParamsValue("oper").equals("edit");
        boolean power=hasAdminOperPower("manage_api_power");
        VueListResult result=getVueListResult("数据列", ApiColumn.class,actionUrl("apiColumnList"));
        result.setSubTitle("添加或者编辑数据列信息。");
        result.addCol(toIndexColumn());
        result.addCol(toTextColumn("字段", "name",true));
        result.addCol(toTextColumn("描述", "description",200,true));
        result.addCol(toTextColumn("类型", "type",true));
        result.addCol(toIntegerColumn("长度", "length",60,true).setCount(ListCount.NONE));
        result.addCol(toTextColumn("非空", "notnull",60,true).setDictOption(ApiColumn.class,"notnull").setAlign(Align.CENTER));
        if(null!=at&&!"B".equals(at.getSource())) {
            result.addCol(toTextColumn("初始化", "isinit",80,true).setDictOption(ApiColumn.class,"isinit").setAlign(Align.CENTER));
            if (power && isEdit) result.addCol(toSpaceColumn("操作", 130,
                ListElement.test("record.isinit!='Y'",
                    ListButton.modal("修改", ButtonType.PRIMARY, actionUrl("toEdit"), 800, SuccessMethod.REFRESH)
                        .addParam("model.oid", "oid")
                ),
                ListElement.test("record.isinit!='Y'",
                    ListButton.ajax("删除", ButtonType.WARN, actionUrl("doDelete"), SuccessMethod.REFRESH)
                        .addParam("model.oid", "oid").setConfirm("确定要删除该字段吗?")
                )
            ).setFixed(Align.RIGHT));
            if (power && isEdit) result.addButton(
                ListButton.modal("新增", ButtonType.PRIMARY, actionUrl("toEdit"), 800, SuccessMethod.REFRESH)
                    .addQueryParam("model.table.oid", "tableOid")
            );
        }
        if(null!=at&&"B".equals(at.getSource())) {
            if (power && isEdit) result.addButton(
                ListButton.ajax("更新列信息", ButtonType.PRIMARY, actionUrl("updateColumns"), SuccessMethod.REFRESH)
                    .addQueryParam("tableOid", "tableOid").setConfirm("确定要更新列信息吗？")
            );
        }
        result.addCondition(QueryCondition.eq("table.oid",tableOid));
        return result;
    }
    public ApiColumn getModel() {
        return model;
    }


    public void setModel(ApiColumn model) {
        this.model = model;
    }
}
